\documentclass[10pt, a4paper]{article}
\usepackage[paper=a4paper, left=1.5cm, right=1.5cm, bottom=1.5cm, top=3.5cm]{geometry}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[spanish]{babel}
\usepackage{indentfirst}
\usepackage{fancyhdr}
\usepackage{latexsym}
\usepackage{lastpage}
\usepackage{caratula}
\usepackage[colorlinks=true, linkcolor=black]{hyperref}
\usepackage{calc}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{graphicx}

\usepackage{lmodern}

\newcommand{\f}[1]{\text{#1}}

\sloppy

%Datos de la caratula
\materia{Sistemas Operativos}
\titulo{Trabajo pr\'actico 2}
\grupo{Grupo Dame el Hash}
\integrante{Lizana, Helen}{118/08}{hsle.22@gmail.com}
\integrante{Rabazano, Nancy}{720/09}{nrabazano@gmail.com}
\integrante{L\'opez, Juan Ignacio}{034/10}{juan.lopez848@gmail.com}


\hypersetup{%
 % Para que el PDF se abra a página completa.
 pdfstartview= {FitH \hypercalcbp{\paperheight-\topmargin-1in-\headheight}},
 pdfauthor={Lizana, Rabazano, L\'opez},
 pdfsubject={TP2}
}

\parskip=5pt % 10pt es el tamaño de fuente

% Pongo en 0 la distancia extra entre ítemes.
\let\olditemize\itemize
\def\itemize{\olditemize\itemsep=0pt}

% Acomodo fancyhdr <- Creo que es el encabezado de pagina
\pagestyle{fancy}
\thispagestyle{fancy}
\addtolength{\headheight}{1pt}
\lhead{Sistemas Operativos, TP2}
\rhead{2$^{do}$ Cuatrimestre 2013}
\cfoot{\thepage}
\renewcommand{\footrulewidth}{0.4pt}
	


\begin{document}

%Pagina de titulo e indice
\thispagestyle{empty}

\maketitle
\tableofcontents

\newpage

\newenvironment{myindentpar}[1]
{\begin{list}{1}
         {\setlength{\leftmargin}{#1}}
         \item[]
}
{\end{list} }

% Archivos entregados
% \newpage
% \input{Archivos/archivos.txt}


\newpage
% Intro
\input{Ejercicios2/Introduccion/main.txt}

% Ejercicio 1
\input{Ejercicios2/Ej1/main.txt}

\section{Servidor backend multithread}


\indent Se busca que las conexi\'ones de los \textit{controladores} se hagan en simult\'aneo 
al desarrollo del juego, permitiendo que el \textit{controlador} pueda consultar en cualquier 
momento el estado del mismo. Por lo tanto, se hace  necesario contar con un \textit{thread} 
aparte que se encargue de ir atendiendo a cada uno de los \textit{controladores} que piden 
conectarse al \textit{servidor}.\\

\indent Por otra parte, la atenci\'on de cada \textit{controlador} se hace en un nuevo 
\textit{thread} en el cu\'al ejecuta el c\'odigo correspondiente al control del mismo. De esta manera 
permitimos que varios \textit{controladores} puedan correr concurrentemente.\\

\begin{itemize}
\item Los \textit{controladores} ser\'an ser atendidos un \textit{thread} aparte.\\
\item Dicho \textit{thread} abre un socket para que puedan conectarse los \textit{controladores}.\\
\item Para cada \textit{controlador} que se conecta, se crea otro \textit{thread} encargado de 
ejecutar el m\'etodo \textbf{\textit{atender\_controlador}}.\\ 
\item Finalmente, se hace \textit{join} de los \textit{threads} para esperar la finalizaci\'on de los 
procesos y cerrar el socket una vez que estos hayan finalizado.\\
\end{itemize}

\subsection{Implementaci\'on}
\indent En el main del servidor (server.cpp) se crea el \textit{thread} que atiende la conexi\'on 
de los \textit{controladores}: \\

\begin{verbatim}
	  pthread_t controler_thread;
	  pthread_create(&thread_controladores, NULL, recibir_controlador, NULL);
\end{verbatim}

\indent El thread ejecuta el m\'etodo \textit{thread\_controladores} que se encarga de abrir un socket, 
al cual se conectar\'an los distintos \textit{controladores \'o clientes}, y de crear 
los \textit{threads} para cada \textit{controlador} que se conecta: \\
	
\begin{verbatim}
void * recibir_controlador(void *arg){

	int port_controlador = CONTROLLER_PORT;

	/* Crear socket sobre el que se lee: dominio INET, protocolo TCP (STREAM). */
	sock_controladores = socket(AF_INET, SOCK_STREAM, 0);
	if (sock_controladores < 0) {
		perror("abriendo socket");
		exit(1);
	}
	/* Crear nombre, usamos INADDR_ANY para indicar que cualquiera 
	puede enviar aquí. */
	name_controlador.sin_family = AF_INET;
	name_controlador.sin_addr.s_addr = INADDR_ANY;
	name_controlador.sin_port = htons(port_controlador);
	if (bind(sock_controladores, (const struct sockaddr*) 
	&name_controlador, sizeof(name_controlador))) {
		perror("binding socket");
		exit(1);
	}
	
	/* Escuchar en el socket y permitir n conexiones en espera. */
	if (listen(sock_controladores, MAX_CONTROLADORES) == -1) {
		perror("escuchando");
		exit(1);
	}

	// Acepto los controladores
	int t;
	for (int i = 0; i < MAX_CONTROLADORES; i++) {
		t = sizeof(remote);
		if ((controlador[i] = accept(sock_controladores, 
		(struct sockaddr*) &remote, (socklen_t*) &t)) == -1) {
			perror("aceptando la conexión entrante");
			exit(1);
		}

		int flag = 1;
		setsockopt(controlador[i],  /* socket affected */
				IPPROTO_TCP,     	/* set option at TCP level */
				TCP_NODELAY,     	/* name of option */
				(char *) &flag,  	/* the cast is historical */
				sizeof(int));    	/* length of option value */

		
		int* c_id = new int; 
		
		// Le paso el id del controlador
		*c_id = i;

		// Creo un thread para atender al controlador
		pthread_create(&thread_controlador[i], NULL, atender_controlador
		, (void *) c_id);

	}

	// Hago join de los threads para esperar que terminen todos.
	for (int i = 0; i < n; i++){
		pthread_join(thread_controlador[i], NULL);
		close(controlador[i]);
		
	}

	return NULL;
}
}
\end{verbatim}

\indent Cada \textit{thread} creado para atender a un \textit{controlador} ejecuta la rutina 
\textit{recibir\_controlador}.

\indent A este m\'etodo	se le ha incorporado un ciclo \textit{while} para que itere recibiendo 
los paquetes del socket 
\begin{verbatim}
  	while (recibido = recv(fd, buf, MAX_MSG_LENGTH, 0)) 
\end{verbatim}



\indent Por otro parte se pide crear un socket  al cual se van a conectar los clientes.

\begin{itemize}
\item Cada jugador se ejecutar\'a en un \textit{thread} a parte.\\
\item Finalmente, se hace \textit{join} de los \textit{threads} para esperar que los 
procesos finalicen y cerrar el socket una vez que estos hayan finalizado.\\
\end{itemize}

\indent El m\'etodo main del servidor (server.cpp)  llama a una a la m\'etodo
\textit{accept} en la cual se crean crea los sockets para cada jugador. Se modific\'o
 el m\'etodo \textit{accept}, de forma que al aceptar un jugador, se cree un thread 
 en el que se ejecute el m\'etodo \textit{atender\_jugador} :
 
\begin{verbatim}
void * atender_jugador(void *arg) {

	int j_id = *((int *) arg);
	int recibido;
	std::string resp;
	while((recibido = recv(s[j_id], buf, MAX_MSG_LENGTH, 0))){

		if (recibido < 0) {
			perror("Recibiendo ");
			
		} else if (recibido > 0) {
			buf[recibido]='\0';
			// Separo los mensajes por el caracter |
			char * pch = strtok(buf, "|");
			while (pch != NULL) {
				// No muestro por pantalla los NOP, son muchos
				if (strstr(pch, "Nop") == NULL) {
				}
				
				//Decodifico el mensaje y obtengo una respuesta
				resp = decoder[j_id]->decodificar(pch);
				
				// Envio la respuesta
				send(s[j_id],resp.c_str(), resp.length() +1, 0);
				
				// No muestro por pantalla los NOP, son muchos
				if (strstr(pch, "Nop") == NULL) {
					printf("Server>> Server>> Resultado %s\n", resp.c_str());
				}
				
				// Si ya se cual es el jugador
				if (j_id != -1) {

					// Busco si hay eventos para enviar y los mando
					bool hayEventos = model->hayEventos(j_id);
					while(hayEventos) {

						resp = decoder[j_id]->encodeEvent(j_id);
						send(s[j_id],resp.c_str(), resp.length() +1, 0);
						hayEventos = model->hayEventos(j_id);
					}
				}
				pch = strtok(NULL, "|");
			}

		}
	}

	return NULL;
}
\end{verbatim}

\indent Por \'ultimo, en el m\'etodo \textit{atender\_jugador} 
se agreg\'o un ciclo \textit{while} para que itere mientras se van recibiendo 
los mensajes del jugador: \\
\begin{verbatim}
	while((recibido = recv(s[j_id], buf, MAX_MSG_LENGTH, 0)))
\end{verbatim}

\indent Se Utiliz\'o un \textit{decodificador} por cada jugador para decodificar sus mensajes. Y adem\'as un buffer para cada jugador y para cada controlador para que no se generen \textit{race conditions}


% Ejercicio 2
\input{Ejercicios2/Ej2/main.txt}

\newpage
\input{Ejercicios2/Conclusion/main.txt}
\end{document}
